package org.geektimes.web.mvc.header;

import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.JSONValidator;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang.StringUtils;
import org.geektimes.base.util.ReflectionUtils;
import org.geektimes.web.mvc.header.matedata.ParamInfo;
import org.geektimes.web.mvc.header.matedata.WebContent;

import javax.servlet.ServletInputStream;
import javax.servlet.http.HttpServletRequest;
import java.lang.reflect.Field;
import java.net.URLDecoder;
import java.util.HashMap;
import java.util.Map;

/**
* 请求体参数处理器  
* @author : KangNing Hu
*/
public class BodyParamParse extends AbstractParamParse{


	private static final String ACCEPT_NAME = "accept";

	private static final String[] JSON_TYPES = {"application/json"  , "*/*" , "application/*"};


	@Override
	public Object parse0(WebContent webContent , ParamInfo paramInfo) {
		HttpServletRequest httpServletRequest = toHttp(webContent.getRequest());
		//校验请求载体类型
		checkContentType(httpServletRequest);
		//处理请求体
		try(ServletInputStream inputStream = httpServletRequest.getInputStream()) {
			///TODO 暂不处理泛型
			String body = IOUtils.toString(inputStream);
			if (StringUtils.isEmpty(body)){
				return null;
			}
			// json
			if (JSONValidator.from(body).validate()) {
				return JSONObject.parseObject(body, paramInfo.getType());
			}
			//data form
			else {
				body = URLDecoder.decode(body, "UTF-8");
				String[] split = body.split("&");
				Map<String ,String > paramMap = new HashMap<>();
				for (String paramValue : split){
					String[] split1 = paramValue.split("=");
					String key = split1[0].trim();
					String value = null;
					if (split1.length == 2){
						value = split1[1].trim();
					}
					paramMap.put(key , value);
				}
				Object obj = null;
				//实体类
				if (!CollectionUtils.isEmpty(paramInfo.getFields())){
					obj = paramInfo.getType().newInstance();
					for (Field field :paramInfo.getFields()){
						ReflectionUtils.set(field , obj , transType(paramMap.get(field.getName()), field.getType()));
					}
				}
				//一般类型
				else {
					obj = paramMap;
				}
				return obj;
			}
		} catch (Exception e) {
			throw new IllegalStateException(e);
		}
	}


	/**
	 * 校验请求体类型
	 * @param httpServletRequest 请求对象
	 */
	private void checkContentType(HttpServletRequest httpServletRequest){
		String contentType = httpServletRequest.getHeader(ACCEPT_NAME);
		for (String jsonType : JSON_TYPES) {
			if (contentType.contains(jsonType)) {
				return;
			}
		}
		throw new IllegalStateException("不支持的" + ACCEPT_NAME + ":" + contentType);
	}
}
